package com.easyarlibrary.artools.ar;//================================================================================================================================
//
//  Copyright (c) 2015-2018 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
//  EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
//  and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//


import android.graphics.Bitmap;
import android.opengl.GLES20;

import com.easyarlibrary.app.BaseAppConstant;
import com.easyarlibrary.util.GlViewUtil;
import com.easyarlibrary.util.ImageUtils;
import com.easyarlibrary.util.LogUtil;

import java.util.ArrayList;

import cn.easyar.Buffer;
import cn.easyar.CameraCalibration;
import cn.easyar.CameraDevice;
import cn.easyar.CameraDeviceType;
import cn.easyar.CameraFrameStreamer;
import cn.easyar.Frame;
import cn.easyar.Image;
import cn.easyar.ImageTracker;
import cn.easyar.Renderer;
import cn.easyar.TargetInstance;
import cn.easyar.TargetStatus;
import cn.easyar.Vec2I;
import cn.easyar.Vec4I;

import static cn.easyar.CameraDeviceFocusMode.Continousauto;

/**
 * createTime：2019/2/25/025 on 17:04
 *
 * @author: jyc dell
 */
public abstract class BaseAR {

    protected CameraDevice camera;
    protected CameraFrameStreamer streamer;
    protected ArrayList<ImageTracker> trackers;
    protected Renderer videobg_renderer;
    protected boolean viewport_changed = false;
    protected Vec2I view_size = new Vec2I(0, 0);
    protected int rotation = 0;
    //    protected Vec4I viewport = new Vec4I(0, 0, 1280, 720);
    protected Vec4I viewport = new Vec4I(0, 0, BaseAppConstant.Screen.width, BaseAppConstant.Screen.height);
    //    protected Vec4I viewport = new Vec4I(0, 0, BaseAppConstant.Screen.width / 2, BaseAppConstant.Screen.height / 2);
    private long startTime;

    public BaseAR() {
        trackers = new ArrayList<ImageTracker>();
    }

    public boolean initialize() {
        camera = new CameraDevice();
        streamer = new CameraFrameStreamer();
        streamer.attachCamera(camera);
        boolean status = true;
        status &= camera.open(CameraDeviceType.Back);
//        camera.setSize(new Vec2I(1280, 720));
        camera.setSize(new Vec2I(BaseAppConstant.ArPhotoSize.width, BaseAppConstant.ArPhotoSize.height));
//        camera.setSize(new Vec2I(BaseAppConstant.Screen.width / 2, BaseAppConstant.Screen.height / 2));
        if (!status) {
            return status;
        }
        initCloud();
        ImageTracker tracker = new ImageTracker();
        tracker.attachStreamer(streamer);
        initData(tracker);
        trackers.add(tracker);

        return status;
    }

    protected void initCloud() {
    }

    public void dispose() {
        for (ImageTracker tracker : trackers) {
            tracker.dispose();
        }
        trackers.clear();
        if (videobg_renderer != null) {
//            videobg_renderer.dispose();
            videobg_renderer = null;
        }
        if (streamer != null) {
//            streamer.stop();
//            streamer.dispose();
            streamer = null;
        }
        if (camera != null) {
            if (camera.isOpened()) {
                camera.close();
            }
            camera = null;
        }
    }

    public boolean start() {
        if (camera == null) {
            return false;
        }
        boolean status = true;
        status &= (camera != null) && camera.start();
        status &= (streamer != null) && streamer.start();
        camera.setFocusMode(Continousauto);
        for (ImageTracker tracker : trackers) {
            status &= tracker.start();
        }
        return status;
    }

    public boolean stop() {
        boolean status = true;
        for (ImageTracker tracker : trackers) {
            status &= tracker.stop();
        }
        status &= (streamer != null) && streamer.stop();
        status &= (camera != null) && camera.stop();
        return status;
    }

    public void initGL() {
        if (videobg_renderer != null) {
            videobg_renderer.dispose();
        }
        videobg_renderer = new Renderer();
    }

    public void resizeGL(int width, int height) {
        view_size = new Vec2I(width, height);
        viewport_changed = true;
    }

    /**
     * 结果是被成功重新刷新页面
     */
    private void updateViewport() {
        CameraCalibration calib = camera != null ? camera.cameraCalibration() : null;
        int rotation = calib != null ? calib.rotation() : 0;
        if (rotation != this.rotation) {
            this.rotation = rotation;
            viewport_changed = true;
        }
        if (viewport_changed) {
            Vec2I size = new Vec2I(1, 1);
            if ((camera != null) && camera.isOpened()) {
                size = camera.size();
            }
            if (rotation == 90 || rotation == 270) {
                size = new Vec2I(size.data[1], size.data[0]);
            }
            float scaleRatio = Math.max((float) view_size.data[0] / (float) size.data[0], (float) view_size.data[1] / (float) size.data[1]);
            Vec2I viewport_size = new Vec2I(Math.round(size.data[0] * scaleRatio), Math.round(size.data[1] * scaleRatio));
            viewport = new Vec4I((view_size.data[0] - viewport_size.data[0]) / 2, (view_size.data[1] - viewport_size.data[1]) / 2, viewport_size.data[0], viewport_size.data[1]);

            if ((camera != null) && camera.isOpened()) {
                viewport_changed = false;
            }
        }
    }

    /**
     * 识别结果处理
     */
    public void render() {
        synchronized (BaseAR.class) {
            GLES20.glClearColor(1.f, 1.f, 1.f, 1.f);
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
            if (videobg_renderer != null) {
                Vec4I default_viewport = new Vec4I(0, 0, view_size.data[0], view_size.data[1]);
                GLES20.glViewport(default_viewport.data[0], default_viewport.data[1], default_viewport.data[2], default_viewport.data[3]);
                if (videobg_renderer == null) {
                    return;
                }
                if (videobg_renderer.renderErrorMessage(default_viewport)) {
                    return;
                }
            }
            if (streamer == null) {
                return;
            }
            Frame frame = null;
            try {
                updateViewport();
                GLES20.glViewport(viewport.data[0], viewport.data[1], viewport.data[2], viewport.data[3]);
                if (streamer == null) {
                    return;
                }
                frame = streamer.peek();
                if (videobg_renderer != null) {
                    videobg_renderer.render(frame, viewport);
                }
                long endTime = System.currentTimeMillis();

                if (endTime - startTime < 600) {
                    return;
                }
                startTime = endTime;
                LogUtil.d("开始进入EasyAR识别");
                ArrayList<TargetInstance> targetInstances = frame.targetInstances();

                if (targetInstances.size() > 0 && targetInstances.get(0).target() != null) {
                    TargetInstance targetInstance = targetInstances.get(0);
                    int status = targetInstance.status();
                    if (status == TargetStatus.Tracked) {
                        /**
                         * bitmap预览图获取方式一
                         */
                        Image i = frame.images().get(0);
                        Buffer buffer = i.buffer();
                        byte[] bytes1 = new byte[buffer.size()];
                        buffer.copyTo(bytes1, 0);
                        int[] rgb = new int[i.width() * i.height()];
                        ImageUtils.convertYUV420SPToARGB8888(bytes1, i.width(), i.height(), rgb);
                        Bitmap bitmap = Bitmap.createBitmap(i.width(), i.height(), Bitmap.Config.ARGB_8888);
                        bitmap.setPixels(rgb, 0, i.width(), 0, 0, i.width(), i.height());
                        //由于相机可能存在图片旋转，需要做处理
                        bitmap = ImageUtils.rotate(bitmap,rotation);
                        System.out.println("00000" + bitmap == null ? "000" : "1111");
                        System.out.println("this.rotation----->" + rotation);

                        /**
                         * bitmap预览图获取方式二
                         */
//                        GlViewUtil.createBitmapFromGLSurface(0,0,i.width(),i.height(),gl10)
                        doResule(targetInstance);
                    }
                } else {
                    LogUtil.d("EasyAR未识别出结果");
                }
            } finally {
                if (frame != null) {
                    frame.dispose();
                }
            }
        }
    }

    /**
     * 初始化数据
     *
     * @param targetInstance
     */
    protected void initData(ImageTracker targetInstance) {
    }

    /**
     * 处理识别结果
     *
     * @param targetInstance
     */
    protected void doResule(TargetInstance targetInstance) {
    }
}
